﻿using BugSplattr.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;


namespace BugSplattr
{
    public class BugSplatService
    {
        private static BugSplatService _instance = null;                                    // Singleton established for this instance of BugSplatService (and thus, the only instance)

        private List<WorkItem> _workItems { get; set; }                                     // Creates a singleton list to store objects created

        private int _seedId;                                                                // Singleton established for the ID number assigned to each object

        public static BugSplatService Instance                                              // A public accessor to the singleton, to instantiate the service (from the controller). This turns the servie "on", and lets everything inside get values
        {
            get
            {
                if (_instance == null)                                                      // If the singleton _instance is null, which if you look above it is, then...
                {
                    _instance = new BugSplatService();                                      // ...then the BugSplatService in its entirety is now "turned on"
                }
                return _instance;                                                           // If the singleton is not null, then it will simply do whatever the _service singleton asked it to do.  See how _service is used in the controller for more information
            }
        }
        private BugSplatService()                                                           // Creates a private constructor to activate the singletons in the service
        {
            _seedId = 0;                                                                    // Assigns the _seedId to an initial value of 0
            _workItems = new List<WorkItem>();                                              // Generates an empty list (that can now be used because it is instantiated) in the _workItems singleton
            _seedId++;                                                                      // Counts the _seedId up to 1, so the first object created will have an Id of "1". Subsequent creations will have a higher value, as you will see below
        }
        public List<WorkItem> GetTodos()                                                    // When the controller asks the service for the list, which is private, this public list will be filled with _workItems and shuttled back to the controller
        {
            return _workItems;                                                              // This is the return that shuttles the information in the private list back to the controller.  Read above
        }
        public WorkItem GetWorkItem(int id)                                                 // When the controller asks the service for only a single object (for an edit or update or whatever), this does that
        {
            return _workItems.FirstOrDefault(x => x.Id == id);                              // Finds the object based on the id the controller asked for, and shuttles it back to the controller
        }

        public int CreateBug(string title, DateTime date, int priority, string steps)       // This is the service action that will create a bug. Note the parameters passed in
        {
            int id = _seedId;                                                               // Assigns the new object's id to the current value of _seedId (if it's the first object, it will be 1)
            Bug nBug = new Bug(id, title, date, priority, steps);                           // Creates a new bug with the information given by the controller (again, note the paramaters - this is sent to the constructor)
            _workItems.Add(nBug);                                                           // Adds the newly created bug to the _workItems list
            _seedId++;                                                                      // Sets the _seedId to it's current value + 1 (if the first object was created here, then now the _seedId is 2, so the next object will be at id = 2)
            return nBug.Id;                                                                 // Sends the id of the new bug back to the controller. Doesn't seem to do much, but why not
        }
        public int CreateTask(string title, DateTime date, int priority, string desc)       // This is the service action that will create a task. Note the parameters passed in
        {
            int id = _seedId;                                                               // Assigns the new object's id to the current value of _seedId (read above for more info)
            TaskToDo nTask = new TaskToDo(id, title, date, priority, desc);                 // Creates a new task with the information given by the controller (again, note the paramaters - this is sent to the constructor) 
            _workItems.Add(nTask);                                                          // Adds the newly created task to the _workItems list
            _seedId++;                                                                      // Sets the _seedId to it's current value + 1 (read above for more info)
            return nTask.Id;                                                                // Again, doesn't seem to do much, but why not
        }
        public WorkItem BugToUpdate(int id)                                                 // This is the service action that will get information for the controller to fill Html fields when editing a bug object already in the list
        {
            WorkItem uBug = _workItems.FirstOrDefault(t => t.Id == id);                     // Gets the information from the _workItems list and assigns it to a WorkItem (for future casting in to a Bug by the controller)
            return uBug;                                                                    // Shuttles the information back to the controller to be recasted
        }
        public void UpdateBug(int id, string title, string steps)                           // This is the service action that will update the object in the private list _workItems (note the parameters)
        {
            WorkItem upBug = _workItems.FirstOrDefault(b => b.Id == id);                    // Grabs the item to be edited from the list based on its id (passed in from the controller)
            Bug uBug = (Bug)upBug;                                                          // Casts the WorkItem upBug in to a Bug, then assigns it to the Bug uBug. Now uBug equals the object in the list, and its Bug class properties can be edited (StepsToReproduce)
            _workItems.Remove(upBug);                                                       // Removes the existing object from the list
            if (upBug == null)                                                              // If upBug never had any value because there was no item in the list with the given Id, this terminates the process with the below return.  Prevents an error from being thrown by simply returning nothing and allowing the controller to return the viewer to the index
            {
                return;                                                                     // ...the aforementioned return
            };
            uBug.Title = title;                                                             // Changes uBug's Title property to the user altered version
            uBug.StepsToReproduce = steps;                                                  // Changes uBug's StepsToReproduce property to the user altered version
            _workItems.Add(uBug);                                                           // Adds uBug to the list, to replace the original item which was deleted (note that it's probably not necessary to delete the original item in the first place, this was done during bug testing and left in because there was no reason to remove it once all bugs had been cleared)
        }
        public WorkItem TaskToUpdate(int id)                                                // This is the service action that will get information for the controller to fill Html fields when editing a task object already in the list
        {
            WorkItem uTask = _workItems.FirstOrDefault(t => t.Id == id);                    // Gets the information from the _workItems list and assigns it to a WorkItem (for future casting in to a TaskToDo by the controller)
            return uTask;                                                                   // Shuttles the information back to the controller to be recasted
        }
        // Update a WorkItem
        public void UpdateTask(int id, string title, string desc)                           // This is the service action that will update the object in the private list _workItems (note the parameters)
        {
            WorkItem upTask = _workItems.FirstOrDefault(b => b.Id == id);                   // Grabs the item to be edited from the list based on its id (passed in from the controller)
            TaskToDo uTask = (TaskToDo)upTask;                                              // Casts the WorkItem in to a TaskToDo, then assigns it to the TaskToDo uTask.  Now uTask equals the object in the list, and its TaskToDo class properties can be edited (Description)
            _workItems.Remove(upTask);                                                      // Removes the existing object from the list
            if (upTask == null)                                                             // If upTask never had any value because there was no item in the list with the given Id, this terminates the process with the below return.  Prevents an error from being thrown by simply returning and allowing the controller to return the viewer to the index
            {
                return;                                                                     // The aforementioned return
            };
            uTask.Title = title;                                                            // Changes uTask's Title property to the user altered version
            uTask.Description = desc;                                                       // Changes uTask's Description property to the user altered version
            _workItems.Add(uTask);                                                          // Adds uTask to the list, to replace the original item which was deleted (read above to see why deleting may not have been necessary)
        }
        public void DeleteBug(int id)                                                       // This is the service action that will delete an object from the list
        {
            WorkItem dBug = _workItems.FirstOrDefault(t => t.Id == id);                     // Gets the position in the list based on the id handed down from the controller
            _workItems.Remove(dBug);                                                        // Deletes the offending object from the list
        }
    }
}